# coding = utf-8
import datetime
import os
import time

from django.contrib.auth.hashers import make_password
from django.db.models import Q
from project import settings
from rest_framework import status, mixins
from rest_framework.generics import ListAPIView
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.viewsets import ModelViewSet, ReadOnlyModelViewSet, GenericViewSet
from users.api.utils import jwt_response_payload_handler, jwt_decode_handler, login_record, get_ip

from users.models import UserInfo, Role, Permission, UserLog
from .serializers import UserInfoSerializer, RoleSerializer, PermissionTreeSerializer, \
    JSONWebTokenSerializer, PermissionListSerializer, RolePermsSerializer, RoleListSerializer, \
    UserInfoReadOnlySerializer, PasswordChangeSerializer, UserLogSerializer, PasswordSerializer


class JSONWebTokenAPIView(APIView):
    """
    JWT API View .
    """
    permission_classes = ()
    authentication_classes = ()

    def post(self, request, *args, **kwargs):
        request.data["ip"] = get_ip(request)
        data = request.data
        serializer = JSONWebTokenSerializer(data=data)
        if serializer.is_valid():
            # 记录登录
            login_record(**data, desc='登录成功')

            user = serializer.validated_data["user"]
            token = serializer.validated_data["token"]
            response_data = jwt_response_payload_handler(token, user, request)
            response = Response(response_data)

            return response

        login_record(**data, desc='登录失败')
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class UserLogoutAPIView(APIView):
    """用户退出登录"""
    def post(self, request, *args, **kwargs):
        request.data["ip"] = get_ip(request)
        login_record(**request.data, desc="用户退出")
        msg = {
            "status_code": status.HTTP_200_OK,
            "message": "用户已经退出"
        }
        return Response(msg)


class PasswordChangeAPIView(APIView):
    """
    修改密码.
    """
    permission_classes = ()

    def post(self, request, *args, **kwargs):
        serializer = PasswordChangeSerializer(data=request.data)
        if serializer.is_valid():
            msg = {
                "status_code": status.HTTP_200_OK,
                "message": "密码修改成功!",
            }
            response = Response(msg)

            return response

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class PasswdChangeAPIView(APIView):
    """
    修改密码.
    """
    permission_classes = ()

    def post(self, request, *args, **kwargs):
        serializer = PasswordSerializer(data=request.data)
        if serializer.is_valid():
            msg = {
                "status_code": status.HTTP_200_OK,
                "message": "密码修改成功!",
            }
            response = Response(msg)

            return response

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class UserInfoViewSet(ModelViewSet):
    # authentication_classes = ()
    permission_classes = ()
    # pagination_class = None
    queryset = UserInfo.objects.all()
    serializer_class = UserInfoSerializer

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.validated_data["password"] = make_password(serializer.validated_data["password"])
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

    def get_queryset(self):
        queryset = super(UserInfoViewSet, self).get_queryset()
        name = self.request.query_params.get("name", None)
        print(name)
        if name:
            queryset = queryset.filter(Q(name__contains=name) | Q(real_name__contains=name))

        return queryset


class UserInfoReadOnlyViewSet(APIView):
    # authentication_classes = ()
    permission_classes = ()

    def get(self, request, *args, **kwargs):
        token = request.query_params.get("token")
        payload = jwt_decode_handler(token)
        user_id = payload.get("user_id")
        user = UserInfo.objects.filter(id=user_id).first()

        serializer = UserInfoReadOnlySerializer(user, context={"request": request})
        return Response(serializer.data)


class UserInfoListAPIView(ListAPIView):
    """用户列表"""
    permission_classes = ()
    pagination_class = None
    queryset = UserInfo.objects.filter(is_superuser=False)
    serializer_class = UserInfoReadOnlySerializer


class RoleViewSet(ModelViewSet):
    # authentication_classes = ()
    permission_classes = ()
    queryset = Role.objects.all()
    serializer_class = RoleSerializer


class RoleListViewSet(ModelViewSet):
    # authentication_classes = ()
    permission_classes = ()
    pagination_class = None
    queryset = Role.objects.all()
    serializer_class = RoleListSerializer


class RolePermsViewSet(ReadOnlyModelViewSet):
    # authentication_classes = ()
    permission_classes = ()
    pagination_class = None
    queryset = Permission.objects.filter(parent=None)
    serializer_class = RolePermsSerializer

    def get_queryset(self):
        queryset = super(RolePermsViewSet, self).get_queryset()
        user = self.request.user
        # print(user)
        if not isinstance(user, UserInfo):
            return None

        if user.is_superuser:
            return queryset
        perms = user.roles.filter(permissions__id__isnull=False).values("permissions")
        queryset = queryset.filter(id__in=perms)
        return queryset


class PermissionViewSet(ModelViewSet):
    # authentication_classes = ()
    permission_classes = ()
    # pagination_class = None
    queryset = Permission.objects.all()
    serializer_class = PermissionTreeSerializer

    def get_queryset(self):
        queryset = super(PermissionViewSet, self).get_queryset()
        if self.lookup_field in self.kwargs:
            return queryset

        name = self.request.query_params.get("name")
        if name:
            queryset = queryset.filter(Q(name__contains=name) | Q(path__contains=name))
        else:
            queryset = queryset.filter(parent__isnull=True)

        return queryset

    def get_serializer_class(self):
        name = self.request.query_params.get("name")
        if name:
            return PermissionListSerializer

        return super(PermissionViewSet, self).get_serializer_class()

    def paginate_queryset(self, queryset):
        search_type = self.request.query_params.get("type")
        # print("paginate_queryset:", search_type, self.pagination_class)
        if search_type == "tree":
            self.pagination_class = None

        return super(PermissionViewSet, self).paginate_queryset(queryset)


class ImageUploadAPIView(APIView):
    # authentication_classes = ()
    def post(self, request, *args, **kwargs):
        # 接收文件
        file_obj = request.FILES.get('file', None)
        name = request.POST.get('name', None)

        if name and file_obj:
            print(name, file_obj.name)
            user = UserInfo.objects.filter(name=name).first()
            if user:
                upload_path = user.avatar.field.upload_to
                dirs = os.path.join(settings.MEDIA_ROOT, upload_path)
                if not os.path.exists(dirs):
                    os.makedirs(dirs)

                img_info = file_obj.name.split(".")
                img_name = img_info[0]
                img_suffix = img_info[1]
                image_name = '{0}_{1}.{2}'.format(img_name, int(time.time()), img_suffix)
                image_path = os.path.join(dirs, image_name)

                with open(image_path, 'wb') as f:
                    for chunk in file_obj.chunks():
                        f.write(chunk)

                image_url = '{0}{1}'.format(upload_path, image_name)
                user.avatar = image_url
                user.save()
                msg = {
                    "status_code": status.HTTP_200_OK,
                    "image_url": image_url
                }
                return Response(msg)

        return Response({"status_code": status.HTTP_401_UNAUTHORIZED, "message": "上传失败!"})


class UserLogViewSet(mixins.ListModelMixin, GenericViewSet):
    """用户登录日志"""
    # authentication_classes = ()
    permission_classes = ()
    queryset = UserLog.objects.all()
    serializer_class = UserLogSerializer

    def get_queryset(self):
        queryset = super(UserLogViewSet, self).get_queryset()
        user = self.get_user()
        if user is None:
            return None

        if user.is_superuser:
            return queryset

        queryset = queryset.filter(username=user.name)[0: 20]

        return queryset

    def paginate_queryset(self, queryset):
        # user = self.get_user()
        # if user:
        #     if not user.is_superuser:
        #         self.pagination_class = None

        return super(UserLogViewSet, self).paginate_queryset(queryset)

    def get_user(self):
        user = self.request.user
        if isinstance(user, UserInfo):
            return user
        return None




